package com.lishui.waterfriend.task;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.lishui.waterfriend.common.result.PageResult;
import com.lishui.waterfriend.contant.RedisVarConstant;
import com.lishui.waterfriend.mapper.UserMapper;
import com.lishui.waterfriend.pojo.entity.User;
import com.lishui.waterfriend.pojo.vo.UserVO;
import com.lishui.waterfriend.properties.RedissonProperties;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Component
@Slf4j
public class PreCacheTask {

    @Resource
    private UserMapper userMapper;

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Resource
    private RedissonClient redissonClient;

    @Resource
    private RedissonProperties redissonProperties;
    //一页用户数
    public static final Integer pageSize = 4;

    // 每天23:58更新缓存
    @Scheduled(cron = "0 58 23 * * ? ")
    // @Scheduled(cron = "*/30 * * * * ? ")
    public void preRecommendUserCache() {
        RLock lock = redissonClient.getLock(RedisVarConstant.PRELOADING_LOCK);
        try {
            // 只有一个线程能拿到锁
            if (lock.tryLock(0, -1, TimeUnit.MILLISECONDS)) {
                // Thread.sleep(40000);
                log.info("Lock:{} 更新推荐用户缓存 {}", Thread.currentThread().getId(), new Date());
                ValueOperations<String, Object> ValueOperations = redisTemplate.opsForValue();
                QueryWrapper<User> queryWrapper = new QueryWrapper<>();
                List<User> userList = userMapper.selectList(queryWrapper);
                Integer total = userList.size();
                int maxPageNum = (int) Math.ceil(total / pageSize.doubleValue());
                log.info("maxPageNum：{}", maxPageNum);
                userList.forEach(user -> {
                    for (int pageNum = 1; pageNum <= maxPageNum; pageNum++) {
                        String redisKey = String.format(RedisVarConstant.USER_PAGE_RECOMMEND_KEY, user.getId().toString(), pageNum, pageSize);
                        PageHelper.startPage(pageNum, pageSize);
                        QueryWrapper<User> pageQueryWrapper = new QueryWrapper<>();
                        List<User> pageUserList = userMapper.selectList(pageQueryWrapper);
                        PageInfo<User> pageInfo = new PageInfo<>(userList);
                        PageResult pageResult = new PageResult(pageInfo.getTotal(), pageUserList.stream().map(u -> {
                            UserVO userVO = new UserVO();
                            BeanUtils.copyProperties(u, userVO);
                            return userVO;
                        }).collect(Collectors.toList()));
                        ValueOperations.set(redisKey, pageResult, 23, TimeUnit.HOURS);
                    }
                });
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            // 最后释放自己的锁
            if (lock.isHeldByCurrentThread()) {
                log.info("unLock: " + Thread.currentThread().getId());
                lock.unlock();
            }
        }
    }
}
